#include<iostream>
#include<fstream>
#include<vector>
#include<string>
#include<boost/filesystem.hpp>
#include<unistd.h>
#include"util.hpp"
#include"log.hpp"


const std::string src_path="./data/input/";
const std::string output="./data/output/raw.txt";

struct DocInfo
{
    std::string title;      //标题
    std::string content;    //内容
    std::string url;        //url
};

//状态机
enum status
{
    content_,
    tab_
};


//规定
//值输入
//*输出
//&输入输出

//1、枚举文件
namespace fs=boost::filesystem;

bool EnumFile(const std::string &root_path,std::vector<std::string> *file_col)
{
    int count=0;
    //枚举html文件路径
    fs::path path(root_path);
    if(!fs::exists(path))
    {
        std::cerr<<"路径不存在"<<std::endl;
        return false;
    }
    //用于判断结束
    fs::recursive_directory_iterator end;
    for(fs::recursive_directory_iterator iter(path);iter!=end;iter++)
    {
        if(!fs::is_regular_file(*iter))
        {
            continue;
        }
        if(iter->path().extension()!=".html")
        {
            continue;
        }
        count++;
        //std::cout<<"debug:"<<iter->path().string()<<"num:"<<count<<std::endl;
        LOG(DEBUG,iter->path().string()+" num:"+std::to_string(count));
        file_col->push_back(iter->path().string());
    }
    return true;
}

//2、去标签，分析文件内容
bool ParseHtml(const std::vector<std::string> &file_col,std::vector<DocInfo> *DocInfo_col)
{
    //遍历每一个文件
    int count=0;
    for(auto& path:file_col)
    {
        std::string raw_file;
        if(!util::FileUtil::ReafFile(path,&raw_file))
        {
            //std::cout<<"ReadFile error"<<std::endl;
            LOG(WARNING,"读取文件失败");
            continue;
        }
        //解析文件内容
        //提取title，内容去标签，构建url
        //<title>What's Included in This Document</title>
        //1、提取title
        count++;
        int begin_t=raw_file.find("<title>")+strlen("<title>");
        int end_t =raw_file.find("</title>"); 
        std::string title(raw_file.begin()+begin_t,raw_file.begin()+end_t);
        //2、内容去标签
        std::string content;
        status s=tab_;
        for(auto ch:raw_file)
        {
            if(ch =='<')
            {
                s=tab_;
            }
            else if(ch=='>')
            {
                s=content_;
            }
            else if(s==content_)
            {
                if(ch=='\n')
                {
                    ch=' ';
                }
                content+=ch;
            }
        }
        //3、构建url
        //https://www.boost.org/doc/libs/1_82_0/doc/html/reference.html
        //https://www.boost.org/doc/libs/1_82_0/doc/html/accumulators.html
        
        std::string url="https://www.boost.org/doc/libs/1_82_0/doc/html/"
        +std::string(path,src_path.size());
        //std::cout<<"url: "<<url<<std::endl;
        // std::cout<<"count: "<<count<<std::endl;
        // std::cout<<"title: "<<title<<std::endl;
        // std::cout<<"content: "<<content<<std::endl;
        // std::cout<<"url: "<<url<<std::endl;
        // std::cout<<"path: "<<path<<std::endl;
        //4、 写入vector
        struct DocInfo item;
        item.content=content;
        item.title=title;
        item.url=url;
        DocInfo_col->push_back(std::move(item));

    }
    return true;
}

//3、写入文件
bool SaveHtml(const std::vector<DocInfo> &DocInfo_col,const std::string& output)
{
    int count=0;
    std::ofstream out(output,std::ios::out|std::ios::binary);
    for(auto& item:DocInfo_col)
    {
        //将结构体中每个文件的内容写成title\3content\3url\n的格式，便于之后getline提取
        count++;
        std::string disp_file;
        disp_file=item.title+'\3'+item.content.substr(item.title.size())+'\3'+item.url+'\n';
        //std::cout<<"写入文件中 count: "<<count<<std::endl;
        LOG(NORMAL,"写入文件中 count: "+std::to_string(count));
        //std::cout<<"disp_file: "<<disp_file<<std::endl;
        //写入文件
        if (!out.is_open())
        {
            //std::cerr<<"error"<<std::endl;
            continue;
        }
        out.write(disp_file.c_str(),disp_file.size());
    }
    out.close();
    return true;
}


int main()
{
    //1、枚举文件
    std::vector<std::string> file_col;
    EnumFile(src_path,&file_col);
    //2、去标签，分析文件内容
    std::vector<DocInfo> DocInfo_col;
    ParseHtml(file_col,&DocInfo_col);
    //3、写入文件
    SaveHtml(DocInfo_col,output);
    return 0;
}